//C09:VirtInit.cpp
// Illustrates initialization order with virtual bases.
#include <iostream>
#include <string>
#include <type_traits>
using namespace std;

class M
{
    public:
        M(const string& s) { cout << "M" << s << endl; }
};

class A
{
    M m;
    public:
        A(const string& s) : m("in A")
        {
            cout << "A " << s << endl;
        }
        virtual ~A() {}
};

class B
{
    M m;
    public:
        B(const string& s) : m("in B")
        {
            cout << "B" << s << endl;
        }
        virtual ~B() {}
};

class C
{
    M m;
    C(const string& s) : m("in C")
    {
        cout << "C " << s << endl;
    }
    virtual ~C() {}
};

class D
{
    M m;
    public:
        D(const string& s) : m("in D")
        {
            cout << "D " << s << endl;
        }
        virtual ~D() {}
};

class E : public A, virtual public B, virtual public C
{
    M m;
    public:
        E(const string& s) : A("from E"), B("from E"),
            C("from E"), m("in E")
        {
            cout << "E " << s << endl;
        }    
};

class F : virtual public B, virtual public C, public D
{
    M m;
    public:
        F(const string& s) : B("from F"), C("from F"),
            D("from F"), m("in F")
        {
            cout << "F " << s << endl;
        }
};

class G : public E, public F
{
    M m;
    public:
        G(const string& s) : B("from G"), C("from G"),
            E("from G"), F("from G"), m("in G")
        {
            cout << "G " << s << endl;
        }    
};

int main(void)
{
    G g("from main");
}